import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# 读取文件
df = pd.read_csv("E:/data.csv")

# 在数据处理时，每个中间型与区间型都有其自己的最优指标
mid_best = float(input("请输入中间型指标的最优值："))
interval_best = np.array([])
interval_best = np.append(interval_best, float(input("请输入区间型指标的最优值下限：")))
interval_best = np.append(interval_best, float(input("请输入区间型指标的最优值上限：")))


# 在进行TOPSIS法分析得分时，每种指标得分都要统一转化为最大型指标，即进行原始矩阵正向化


def MinToMax(min):  # 最小型转最大型
    max = np.max(min)
    return max - min


def MidToMax(mid, best):  # 中间型转最大型
    h = abs(mid - best)
    max = np.max(h)
    if max == 0:  # max是要做分母的，如果它恰好为0，则需要进行特殊处理
        max = 1
    return 1 - h / max


def IntervalToMax(interval, best):  # 传入的best是一个列表，best[0]存放区间下限，best[1]存放区间上限
    m = max(abs(best[0] - np.min(interval)), abs(best[1] - np.max(interval)))  # 计算指标值超出区间的最大距离
    if m == 0:
        m = 1
    ret = np.array([])
    for i in interval:
        if i < best[0]:  # 小于下界
            ret = np.append(ret, 1 - (best[0] - i) / m)  # 计算距离比例
        elif i > best[1]:  # 大于上界
            ret = np.append(ret, 1 - (i - best[1]) / m)
        else:
            ret = np.append(ret, 1)  # 刚好在区间内，将值置一
    return ret


df['min_type'] = MinToMax(df.iloc[:, 1])  # 对df中索引为方括号内的一列进行整体赋值。如果用方括号里输入一个不存在的索引，会以此作为索引，将value指向的数据最为新的一列插在df的最后
df['mid_type'] = MidToMax(df.iloc[:, 2], mid_best)
df['interval_type'] = IntervalToMax(df.iloc[:, 3], interval_best)
# 如果想进行尾部插入操作则可以df.loc[len(df)] = 数据，len(df)的值是df的行数
# 逐列进行矩阵标准化
def normalizing(data):
    return data / (data.dot(data) ** 0.5)


df['max_type'] = normalizing(df['max_type'])
df['min_type'] = normalizing(df['min_type'])
df['mid_type'] = normalizing(df['mid_type'])
df['interval_type'] = normalizing(df['interval_type'])
max = np.max(df, axis=0)  # 取出每一行的最值，作为最优与最不优解，计算每个数据与它们的“距离”
min = np.min(df, axis=0)
result = np.array([])


def fun(data, max, min):
    d_pos = (data - max).dot(data - max) ** 0.5
    d_neg = (data - min).dot(data - min) ** 0.5
    return d_neg / (d_pos + d_neg)


result = np.append(result, fun(df.loc[0].values, max, min))
result = np.append(result, fun(df.loc[1].values, max, min))
result = np.append(result, fun(df.loc[2].values, max, min))
print(result)
